package com.hopes.bizz.close.position.support.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Queues;
import com.hopes.bizz.close.basic.entity.ClosedGpsDeviceEntity;
import com.hopes.bizz.close.basic.service.ClosedGpsDeviceService;
import com.hopes.bizz.close.common.constant.BasicDicConstant;
import com.hopes.bizz.close.common.constant.PositionProperties;
import com.hopes.bizz.close.position.entity.ClosedHazardCarPositionHisEntity;
import com.hopes.bizz.close.position.service.ClosedHazardCarPositionHisService;
import com.hopes.bizz.close.position.service.HazardCachePositionService;
import com.hopes.bizz.close.position.support.PositionTaskHandle;
import com.hopes.bizz.close.position.vo.HazardCachePositionVO;
import com.hopes.boss.common.core.constant.CommonConstants;
import com.hopes.boss.common.data.tenant.TenantBroker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author yumr
 * @ProjectName bizz
 * @Description 定位数据定时处理
 * @time 2024/2/4 16:53
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PositionTaskHandleImpl implements PositionTaskHandle {

    private final PositionProperties positionProperties;
    private final ClosedGpsDeviceService closedGpsDeviceService;
    private final HazardCachePositionService hazardCachePositionService;
    private final ClosedHazardCarPositionHisService closedHazardCarPositionHisService;

    private BlockingQueue<ClosedHazardCarPositionHisEntity> blockingQueue;


    @PostConstruct
    public void postConstruct() {
        blockingQueue = new ArrayBlockingQueue<>(positionProperties.getCachePositionQueueCapacity(), true);
    }

    @Override
    public boolean handleCachePosition() {
        final List<HazardCachePositionVO> hazardCachePositionList = hazardCachePositionService.listHazardCarCachePosition();
        if(CollUtil.isEmpty(hazardCachePositionList)) {
            return false;
        }
        // 1、修改 GPS定位卡
        handleUpdateGpsDevice(hazardCachePositionList);
        return true;
    }

    /**
     * 更新GPS定位卡
     * @param hazardCachePositionList  实时缓存的数据
     */
    private void handleUpdateGpsDevice(List<HazardCachePositionVO> hazardCachePositionList) {
        final Map<String, ClosedGpsDeviceEntity> deviceNoEntityMap = closedGpsDeviceService.queryGpsDeviceList().stream().filter(e ->
                StrUtil.isNotBlank(e.getDeviceNo())).collect(Collectors.toMap(ClosedGpsDeviceEntity::getDeviceNo, e -> e));
        hazardCachePositionList.stream().filter(e -> deviceNoEntityMap.containsKey(e.getDeviceNo())).forEach(cachePositionVO -> {
            closedGpsDeviceService.lambdaUpdate()
                    .eq(ClosedGpsDeviceEntity::getDeviceNo, cachePositionVO.getDeviceNo())
                    .set(ClosedGpsDeviceEntity::getDataTime, cachePositionVO.getDataTime())
                    .set(ClosedGpsDeviceEntity::getLatitude, cachePositionVO.getLatitude())
                    .set(ClosedGpsDeviceEntity::getAltitude, cachePositionVO.getAltitude())
                    .set(ClosedGpsDeviceEntity::getLongitude, cachePositionVO.getLongitude())
                    .set(ClosedGpsDeviceEntity::getBindFlag, CommonConstants.DEFAULT_TRUE_FLAG)
                    .set(ClosedGpsDeviceEntity::getNetworkStatus, BasicDicConstant.CLOSE_DEVICE_NETWORK_STATUS_NORMAL).update();
        });
    }

    @Override
    public boolean handleQueuePosition() {
        try {
            final List<ClosedHazardCarPositionHisEntity> tempList = new ArrayList<>();
            Queues.drain(blockingQueue, tempList, blockingQueue.size(), 5, TimeUnit.MILLISECONDS);
            log.debug("批量保存数据数量：{}", tempList.size());
            if (CollUtil.isEmpty(tempList)) {
                return false;
            }
            return closedHazardCarPositionHisService.saveBatch(tempList);
        }catch (Exception e) {
            log.error("定时批量保存历史定位数据异常!", e);
        }
        return false;
    }

    @Override
    public boolean offerQueuePosition(ClosedHazardCarPositionHisEntity hisHazardCarPosition) throws InterruptedException {
        if(ObjUtil.isNull(hisHazardCarPosition)) {
            return false;
        }
        if (blockingQueue.size() >= positionProperties.getCachePositionQueueCapacity() * positionProperties.getCachePositionQueueThreshold()) {
            final boolean handleQueuePosition = handleQueuePosition();
        }
        return blockingQueue.offer(hisHazardCarPosition, 5, TimeUnit.MILLISECONDS);
    }
}
